import { SubmitHandler, useForm } from "react-hook-form"; // 从react-hook-form库中导入SubmitHandler和useForm
import { zodResolver } from "@hookform/resolvers/zod"; // 从@hookform/resolvers/zod库中导入zodResolver，用于集成Zod与react-hook-form
import { z } from "zod"; // 从zod库中导入z，用于创建模式验证

// 定义表单状态接口
interface FormState {
  username: string; // 用户名
  isAgree: boolean; // 是否同意协议
  hobbies: string[]; // 爱好
  gender: string; // 性别
  transport: string; // 交通工具
}

// 定义表单验证模式
const schema = z.object({
  username: z
    .string({
      required_error: "请输入用户名", // 当字段为空时的错误信息
      invalid_type_error: "用户名类型错误", // 当字段类型不正确时的错误信息
    })
    .min(2, { message: "用户名长度不能小于2" }) // 设置用户名最小长度为2，不满足时的错误信息
    .max(6, { message: "用户名长度不能大于6" }), // 设置用户名最大长度为6，不满足时的错误信息
  isAgree: z.literal(true, { errorMap: () => ({ message: "请同意协议" }) }), // 验证是否同意协议，不同意时的错误信息
});
export default function App() {
  // 使用 useForm 钩子函数创建表单对象，该对象将与 form 标签进行绑定
  // register: 用于注册输入控件到 useForm，以便进行数据绑定和验证
  // handleSubmit: 用于处理表单提交事件。它会在提交前进行表单验证，只有通过验证后，才会调用提交处理函数，并传递表单数据
  // formState: 包含表单的状态信息，如是否被触摸、是否有效等
  // errors: 存储表单验证后的错误信息
  // setValue: 允许动态设置输入控件的值
  // reset: 用于重置表单到初始状态或指定的状态
  const {
    register,
    handleSubmit,
    formState: { errors },
    setValue,
    reset,
  } = useForm<FormState>({
    // 设置表单控件的默认值
    defaultValues: {
      username: "张三", // 默认用户名
      isAgree: false, // 默认不同意协议
      hobbies: [], // 默认没有选择爱好
      gender: "女", // 默认性别为女
      transport: "自驾", // 默认交通工具为自驾
    },
    mode: "onBlur", // 验证模式为失焦验证
    resolver: zodResolver(schema), // 使用 zodResolver 进行表单验证，schema 为验证规则
  });
  // 表单提交事件的处理函数，参数 formState 包含了表单的数据
  const onSubmit: SubmitHandler<FormState> = (formState) => {
    console.log("提交了");
    console.log(formState); // 打印提交的表单数据
  };

  // 设置表单值的函数，用于演示如何动态设置表单项的值
  const setFormValue = () => {
    setValue("username", "李四"); // 设置用户名为“李四”
    setValue("isAgree", true); // 设置同意协议
    setValue("hobbies", ["编程"]); // 设置爱好为编程
    setValue("gender", "男"); // 设置性别为男
    setValue("transport", "高铁"); // 设置交通工具为高铁
  };

  // 重置表单的函数，用于将表单重置为指定的默认值
  const onReset = () => {
    reset({
      username: "王五", // 重置用户名为“王五”
      isAgree: false, // 重置为不同意协议
      hobbies: ["唱歌"], // 重置爱好为唱歌
      gender: "男", // 重置性别为男
      transport: "自驾", // 重置交通工具为自驾
    });
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <p>
        <input
          type="text"
          placeholder="请输入用户名"
          {...register("username")} // 注册用户名输入框
        />
        {errors.username && errors.username.message} // 显示用户名输入错误信息
      </p>
      <p>
        <input type="checkbox" {...register("isAgree")} /> // 注册同意协议复选框
        {errors.isAgree && errors.isAgree.message} // 显示是否同意协议的错误信息
      </p>
      <p>
        <input type="checkbox" {...register("hobbies")} value="编程" /> 编程
        <input type="checkbox" {...register("hobbies")} value="唱歌" /> 唱歌
        // 注册爱好复选框，允许多选
      </p>
      <p>
        <input type="radio" value="男" {...register("gender")} /> 男
        <input type="radio" value="女" {...register("gender")} /> 女
        // 注册性别单选框
      </p>
      <p>
        <select {...register("transport")}>
          <option>请选择交通工具</option>
          <option value="飞机"></option>         
          <option value="飞机">飞机</option>
          <option value="高铁">高铁</option>
          <option value="自驾">自驾</option>
        </select>
        // 注册交通工具下拉选择框
      </p>
      <button type="submit">提交</button> // 提交按钮，点击后触发表单提交事件
      <button type="button" onClick={setFormValue}>
        设置表单值
      </button> // 设置表单值按钮，点击后调用 setFormValue 函数设置表单项的值
      <button onClick={onReset}>重置</button> // 重置按钮，点击后调用 onReset 函数重置表单项的值为默认值
    </form>
  );
}